package com.rookie.data.generate.component.generate;

import com.rookie.data.generate.constant.annotation.TimeRange;
import com.rookie.data.generate.constant.enums.ColumnRangeEnum;
import com.rookie.data.generate.model.project.FieldProperties;
import com.rookie.data.generate.model.project.TableColumnEntity;
import com.rookie.data.generate.util.GenerateUtils;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;

public class DateGenerate {

    public static Object generate(TableColumnEntity table, FieldProperties properties, ColumnRangeEnum columnRangeEnum) {
        if (properties == null) {
            properties = new FieldProperties();
        }
        if (properties.getTimeRange() != null){
            processRangeAnnotation(properties.getTimeRange(),properties,columnRangeEnum);
        }
        int[] range = GenerateUtils.getRange(properties, columnRangeEnum);
        int num = range[0] + GenerateUtils.RANDOM.nextInt(range[1] - range[0]);
        switch (columnRangeEnum) {
            case DATE:
                return generateDate(num);
            case TIME:
                return generateTime(num);
            case YEAR:
                return generateYear(num);
            case DATETIME:
                return generateDateTime(num);
            case TIMESTAMP:
                return generateTimestamp(num);
            default:
                return null;
        }
    }

    private static void processRangeAnnotation(TimeRange timeRange, FieldProperties properties, ColumnRangeEnum columnRangeEnum) {
        switch (columnRangeEnum) {
            case DATE:
                properties.setMaxValue(timeRange.year() * 365 + timeRange.month() * 30 + timeRange.day());
                break;
            case TIME:
                properties.setMaxValue(timeRange.hour() * 3600 + timeRange.min() * 60 + timeRange.second());
                break;
            case YEAR:
                properties.setMaxValue(timeRange.year());
                break;
            case DATETIME:
                properties.setMaxValue(timeRange.year() * 525600 + timeRange.month() * 43200 +
                        timeRange.day() * 1440 + timeRange.hour() * 60 + timeRange.min());
                break;
            case TIMESTAMP:
                properties.setMaxValue(timeRange.year() * 525600 * 60 + timeRange.month() * 43200 * 60 +
                        timeRange.day() * 1440 * 60 + timeRange.hour() * 60 * 60 + timeRange.min() * 60 + timeRange.second());
                break;
            default:
        }
    }

    private static String generateDate(int num) {
        return LocalDateTime.now().minusDays(num).format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
    }

    private static String generateTime(int num) {
        long nowTime = System.currentTimeMillis() / 1000;
        return Instant.ofEpochMilli((nowTime - num) * 1000).atZone(ZoneOffset.ofHours(8)).toLocalDateTime().format(DateTimeFormatter.ofPattern("HH:mm:ss"));
    }

    private static String generateYear(int num) {
        return LocalDateTime.now().minusYears(num).format(DateTimeFormatter.ofPattern("yyyy"));
    }

    private static String generateDateTime(int num) {
        return LocalDateTime.now().minusHours(num).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }

    private static String generateTimestamp(int num) {
        return LocalDateTime.now().minusSeconds(num).format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
}
